package net.wanho.shiro;

import net.wanho.entity.Perms;
import net.wanho.entity.Role;
import net.wanho.entity.User;
import net.wanho.service.PermsService;
import net.wanho.service.RoleService;
import net.wanho.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Author：汤小洋
 * Date：2024-01-05 9:14
 * Description：<描述>
 */
public class ShiroRealm extends AuthorizingRealm {

    @Resource
    private UserService userService;

    @Resource
    private RoleService roleService;

    @Resource
    private PermsService permsService;

    /**
     * 认证方法
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 判断用户名是否存在
        String username = (String) authenticationToken.getPrincipal();
        User user = userService.findByUsername(username);
        if (ObjectUtils.isEmpty(user)){
            throw new UnknownAccountException("用户名不存在");
        }

        // 返回AuthenticationInfo，然后交由凭证匹配器进行凭证的判断，默认就是对密码进行判断
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                user.getUsername(), // 用户信息
                user.getPassword(), // 密码
                ByteSource.Util.bytes(user.getSalt()), // 盐值
                this.getName() // realm的名称
        );
        return authenticationInfo;
    }

    /**
     * 授权方法
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = (String) principalCollection.getPrimaryPrincipal();

        // 获取角色信息
        List<Role> roleList =  roleService.findByUsername(username);
        List<String> roles = roleList.stream()
                .map(Role::getName)
                .collect(Collectors.toList());


        // 获取权限信息
        List<String> perms = roleList.stream().flatMap(role -> {
            List<Perms> permsList = permsService.findByRoleId(role.getId());
            return permsList.stream().map(Perms::getName);
        }).collect(Collectors.toList());


        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRoles(roles);
        info.addStringPermissions(perms);

        return info;
    }

}
